home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Taifun / Taifun 048 (1988-02-15)(Ossowski, Stefan)(DE)(PD).zip / Taifun 048 (1988-02-15)(Ossowski, Stefan)(DE)(PD).adf / Mandel / source / getfile.c < prev    next >
C/C++ Source or Header  |  1988-01-23  |  17KB  |  629 lines

  1. #undef DEBUG
  2. /************************************************************************
  3. req.c
  4.     This file contains a general-purpose <requester> that
  5. will prompt the user for a filename input.
  6.     The program actually uses a window instead of a 'Requester'
  7. for greater flexibility. It will take control of your window's
  8. IDCMP Port when called.
  9.  
  10. ***    This material is copyright (c) 1986 by C. Heath of Microsmiths, Inc.
  11. Permission is granted to use these files in any way with the following
  12. exceptions:
  13.  
  14. 1) The files shall not be posted on any telecommunications service, public
  15. or private, except for BIX until January 15, 1987.
  16.  
  17. 2) The files may only be distributed in archive format, with no modifications.
  18. If you make any improvements on the file requester and would like to
  19. generally distribute them, please contact "cheath" on BIX, or write to:
  20.     Microsmiths Inc, PO Box 561, Cambridge, MA 02140
  21.  
  22. 3) The requester may be used in any commercial product, but must be in
  23. object code format.  You are free to make modifications for use in your
  24. product.  Permission is granted to Lattice, Inc, and to Manx, Inc, to
  25. include the source files in archive format.
  26.  
  27.     Thank you, and enjoy.
  28.         ...cheath
  29.  
  30. ************************************************************************/
  31.  
  32. #include <exec/types.h>
  33. #include <exec/devices.h>
  34. #include <intuition/intuition.h>
  35.  
  36. #include <libraries/dos.h>
  37. #include <libraries/dosextens.h>
  38. #include <functions.h>
  39.  
  40. #include "mandel.h"
  41.  
  42. #define FAST register
  43. #define NL NULL
  44. #ifdef DEBUG
  45. #  undef STATIC        /* For the debugger's sake */
  46. #  define STATIC
  47. #endif
  48.  
  49. extern TEXT *dmore(), *dinit();
  50.  
  51. STATIC struct FileLock      *pdir = NL;
  52. STATIC struct FileInfoBlock *dir_info;
  53.  
  54. STATIC struct Window   *eW;        /* Parent Window. Uck    */
  55.  
  56. /* STATIC struct TextAttr MyFont = {
  57.     "topaz.font",TOPAZ_EIGHTY,FS_NORMAL,FPF_ROMFONT };
  58.  */
  59. #define MyFont Topaz80
  60.  
  61. /* FGAD requires a few unique gadget-ids, origined at FGAD    */
  62. /* In the unlikely event this conflicts with any of your gadgets, */
  63. /* change this equate to allow 16 contiguous unique ID's    */
  64.  
  65. #define FGAD    0x76c0L
  66.  
  67. #define FCHARS    FNAME_SIZE    /* Number of chars allowed in file name    */
  68.  
  69. #define DIR_SIZ    DNAME_SIZE    /* Number of chars in a dir name...    */
  70. #define MAX_STR    DIR_SIZ+2L
  71.  
  72. #define DENTS    5L        /* Number of entries on screen   */
  73. /* It's not as simple as changing 'DENTS'...      */
  74.  
  75. #define DSIZE    FCHARS+1L    /* Size of a directory entry   */
  76.  
  77. #define    DBUFSIZ    3000L    /* Number of bytes to allocate for all ents */
  78.  
  79. #define BCOL    1L    /* Background color    */
  80. #define FCOL    2L    /* Foreground color    */
  81.  
  82. #define RHGHT    120L
  83. #define RWDTH    320L
  84.  
  85. #define ZWDTH    270L
  86.  
  87. STATIC char    ubuf[MAX_STR];        /* Undo buffer    */
  88.  
  89. STATIC struct dirent { 
  90.     struct dirent *next; 
  91.     BOOL isfile; 
  92.     char dE[DSIZE+2]; 
  93. };
  94. STATIC struct dirent *FirstEntry;
  95. STATIC struct dirent *NextEntry;
  96.  
  97. STATIC struct dirhead { 
  98.     struct dirent *next; 
  99. };
  100. STATIC struct dirhead ListHead;
  101.  
  102. STATIC long   curent,maxent;
  103. STATIC BOOL   more;
  104. STATIC BOOL   redisplay_flag;
  105.  
  106. STATIC struct Window    *wRq = NL;        /* Requester window   */
  107. STATIC struct RastPort    *wRp;
  108.  
  109. /* Requester "Hailing" prompt */
  110. STATIC struct IntuiText oTxt = {
  111.     2,2,JAM1,10,11,NL, NL ,NL};
  112.  
  113. STATIC struct IntuiText saydir = {
  114.     0,1,JAM2,0,1,&MyFont,(UBYTE *)"(dir) ",NL};
  115.  
  116. STATIC struct IntuiText rname[DENTS] = { /* File name list */
  117.     { 2,1,JAM2,48,1,NL,NL, NL    },
  118.     { 2,1,JAM2,48,1,NL,NL, NL    },
  119.     { 2,1,JAM2,48,1,NL,NL, NL    },
  120.     { 2,1,JAM2,48,1,NL,NL, NL    },
  121.     { 2,1,JAM2,48,1,NL,NL, NL    } 
  122. };
  123.  
  124. /* Display for file name ... */
  125.  
  126. STATIC SHORT oXY2[] = {
  127.     -2,-2, RWDTH-78,-2, RWDTH-78,9, -2,9, -2,-2};
  128. STATIC struct Border thebd = {
  129.     0,0, 2,3,JAM1, 5,oXY2, NL};
  130.  
  131. STATIC struct IntuiText otxt = {
  132.     2,2,JAM1,-40,0,&MyFont,(UBYTE *)"file",NL};
  133. STATIC struct StringInfo osx = { 
  134.     NL ,ubuf, NL,DSIZE,NL,NL,NL,NL,NL,NL,NL,NL,NL};
  135. STATIC struct Gadget ogx = { 
  136.     NL, 60,RHGHT-35,RWDTH-80 ,10,     /* File name gadget */
  137.     GADGHCOMP, RELVERIFY , STRGADGET,
  138.     (APTR)&thebd,NL,&otxt,NL,(APTR)&osx, FGAD+11,NL };
  139.  
  140. STATIC struct Gadget oga = { 
  141.     &ogx, 10,70, ZWDTH,10,   /* Gadgets For   */
  142.     GADGHCOMP, RELVERIFY, BOOLGADGET,     /* Directory entries   */
  143.     NL,NL, &rname[4] ,NL,NL, FGAD+10,NL };
  144. STATIC struct Gadget og9 = {
  145.     &oga, 10,60, ZWDTH,10,
  146.     GADGHCOMP, RELVERIFY, BOOLGADGET,
  147.     NL,NL, &rname[3] ,NL,NL, FGAD+9,NL };
  148. STATIC struct Gadget og8 = {
  149.     &og9, 10,50, ZWDTH,10,
  150.     GADGHCOMP, RELVERIFY, BOOLGADGET,
  151.     NL,NL, &rname[2] ,NL,NL, FGAD+8,NL };
  152. STATIC struct Gadget og7 = {
  153.     &og8, 10,40, ZWDTH,10,
  154.     GADGHCOMP, RELVERIFY, BOOLGADGET,
  155.     NL,NL, &rname[1] ,NL,NL, FGAD+7,NL };
  156. STATIC struct Gadget og6 = {
  157.     &og7, 10,30, ZWDTH,10,
  158.     GADGHCOMP, RELVERIFY, BOOLGADGET,
  159.     NL,NL, &rname[0] ,NL,NL, FGAD+6,NL };
  160.  
  161.  
  162. /* Gadgets for requester  */
  163.  
  164. STATIC SHORT oXY3[] = {
  165.     0,0, 50,0, 50,9, 0,9, 0,0};
  166. STATIC SHORT oXY4[] = {
  167.     2,-2, 48,-2, 52,2, 52,7, 48,11, 2,11, -2,7, -2,2, 2,-2};
  168. STATIC struct Border obd2 = {
  169.     0,0, 2,3,JAM1, 9,oXY4, NL};
  170. STATIC struct Border obd1 = {
  171.     0,0, 3,2,JAM1, 5,oXY3, &obd2};  /* OTAY / CANCEL box */
  172.  
  173. STATIC struct IntuiText ot1 = {
  174.     0,0,JAM1,1,1,&MyFont,(UBYTE *)"  OK  ",NL};
  175. STATIC struct IntuiText ot2 = {
  176.     0,0,JAM1,1,1,&MyFont,(UBYTE *)"Cancel",NL};
  177.  
  178. STATIC struct IntuiText dtxt = {
  179.     2,2,JAM1,-60,0,NL,(UBYTE *)"drawer",NL};
  180. STATIC struct StringInfo os5 = { 
  181.     NL ,ubuf, NL,DIR_SIZ,NL,NL,NL,NL,NL,NL,NL,NL,NL};
  182. STATIC struct Gadget og5 = { 
  183.     &og6, RWDTH/2-80,19,190,10,     /* Directory */
  184.     GADGHCOMP, RELVERIFY, STRGADGET,
  185.     NL,NL,&dtxt,NL,(APTR)&os5, FGAD+5,NL };
  186.  
  187. STATIC struct Image   cc_img;
  188. STATIC struct PropInfo   cc_prop = {
  189.     AUTOKNOB | FREEVERT, 0,0, 0,MAXBODY,0,0,0,0,0,0 };
  190. STATIC struct Gadget og3 = { 
  191.     &og5,RWDTH-39,20,20,60,      /* Scroll Bar   */
  192.     GADGHNONE,GADGIMMEDIATE | FOLLOWMOUSE, PROPGADGET,
  193.     (APTR)&cc_img,NL,NL,NL,(APTR)&cc_prop,FGAD+3,NL };
  194.  
  195. STATIC struct Gadget og2 = { 
  196.     &og3, RWDTH-70,RHGHT-20, 50,10,  /* CANCEL */
  197.     GADGHCOMP,  RELVERIFY, BOOLGADGET,
  198.     (APTR)&obd1,NL, &ot2,NL,NL, FGAD+2,NL };
  199.  
  200. STATIC struct Gadget og1 = { 
  201.     &og2, 20,RHGHT-20, 50,10,    /* OTAY   */
  202.     GADGHCOMP,                    /* Flags    */
  203.     RELVERIFY,                    /* Activation    */
  204.     BOOLGADGET,
  205.     (APTR)&obd1,NL,                /* GadgetRender, SelectRender    */
  206.     &ot1,NL,NL,                    /* IntuiText, MutualExclude,SpecialInfo   */
  207.     FGAD+1,NL };                /* Gadget Id, UserData    */
  208.  
  209. /* Open a requester "Window" */
  210.  
  211. STATIC struct NewWindow NewFiles = {
  212.     160, 30, RWDTH,RHGHT, BCOL,FCOL, NL, /* Fill in AFTER opening ... */
  213.     SMART_REFRESH | ACTIVATE | RMBTRAP | WINDOWDRAG,
  214.     &og1,NL,NL, NL,
  215.     NL, RWDTH,RHGHT,RWDTH,RHGHT, WBENCHSCREEN };
  216.  
  217. IMPORT struct Library    *IntuitionBase;
  218.  
  219. /***************************************************
  220. *  get_fname(window,hail,ddef,ddir);
  221. *
  222. *   Displays a window/requester that
  223. * gets a file name for device,directory,default file, extension
  224. *
  225. *   Calling args:
  226. * window:   Window making the request
  227. * screen:   Screen, if NULL assumed workbench 
  228. *             (* Deleted by Olaf Seibert 6 May 1987 *)
  229. * hail:   Text prompt at top of requester
  230. * ddef:   Input default file-name. Has NO DIRECTORY OR EXTENSION.
  231. * ddir:   Directory of file, may be null
  232.  
  233. /* Set a file-requester with prompt 'hail'   */
  234.  
  235. char *get_fname(cW,hail,ddef,ddir)
  236. struct Window *cW;        /* Calling Window   */
  237. UBYTE    *hail;            /* Hailing prompt   */
  238. char        *ddef;        /* Propable file-name   */
  239. char        *ddir;        /* Directory in which to search   */
  240. {
  241.     struct Screen *screen;    /* screen .... got from the window */
  242.     FAST struct IntuiMessage *imes; /* Wait for message in HERE   */
  243.     FAST struct Gadget    *igad;        /* Get Gadjet Mumbo Jumbo   */
  244.     FAST long    i,class;
  245.     FAST TEXT    *pnam;
  246.  
  247.     FAST char    *retval;
  248.     FAST BOOL    keepon;
  249.  
  250.     if ( ! (eW = cW) )   return NL;
  251.  
  252.     osx.Buffer = ddef;    /* Set default file name   */
  253.     os5.Buffer = ddir;    /* Set default device name   */
  254.  
  255.     for ( i=0; i<DENTS; i++) {
  256.         rname[i].IText = "";
  257.         rname[i].NextText = NL;
  258.     };
  259.  
  260.     NewFiles.Title = eW->Title;
  261.     if ((dir_info = AllocMem((long)sizeof(struct FileInfoBlock),0L)) == NULL)
  262.         return NL;
  263.  
  264.     /* Modified by Olaf Seibert 6 may 1987 */
  265.     screen = cW->WScreen;
  266.     NewFiles.Screen = screen;
  267.     NewFiles.Type = screen->Flags & SCREENTYPE;
  268.     NewFiles.LeftEdge = (screen->Width - RWDTH) / 2;
  269.     NewFiles.TopEdge = (screen->Height - RHGHT) / 2; 
  270.  
  271.     cc_prop.VertBody = MAXBODY;
  272.  
  273. /* 
  274.     if (screen)        (* User supplied a screen *)
  275.     {
  276.         NewFiles.Type = CUSTOMSCREEN;
  277.         NewFiles.Screen = screen;
  278.     }
  279. */
  280.  
  281.     if ( ! (FirstEntry = (struct dirent *)AllocMem((long)DBUFSIZ,0L)) ||
  282.         ! (wRq = (struct Window *)OpenWindow( &NewFiles )) ) {
  283.         if ( FirstEntry )   FreeMem(FirstEntry,(long)DBUFSIZ);
  284.     /* notify("Can't Open Requester..."); */
  285.         FreeMem(dir_info,(long)sizeof(struct FileInfoBlock));
  286.         return NL;
  287.     }
  288.  
  289.     SetWindowTitles(wRq, (CPTR) -1, hail);
  290.  
  291. /* Set up directory, notify any errors...   */
  292.     if ( pnam = dinit(ddir) )   notify(pnam);
  293.  
  294.  
  295. /* This optional line will activate a string gadget, which gets messed    */
  296. /* up by RefreshGadgets ... (intuition bug ?)    */
  297. /*    if ( IntuitionBase->lib_Version > 32 ) {
  298.         ActivateGadget(&ogx,wRq,0L);
  299.     }
  300.  */
  301.  
  302.     wRp = wRq->RPort;
  303.  
  304.     wRq->UserPort = eW->UserPort;
  305.     ModifyIDCMP(wRq,(long)(MOUSEBUTTONS | GADGETDOWN | GADGETUP | MOUSEMOVE));
  306.  
  307.     SetAPen(wRp,1L);
  308.     RectFill(wRp,4L,10L,(long)(RWDTH-5),(long)(RHGHT-4));
  309.  
  310.     oTxt.IText = hail;   /* Set calling arg   */
  311.     oTxt.LeftEdge = (RWDTH - IntuiTextLength(&oTxt)) >> 1L;
  312.     PrintIText(wRp,&oTxt,0L,0L);
  313.  
  314.     RefreshGadgets(&og1,wRq,(long)NL);
  315.     for ( retval= NL, keepon=TRUE; keepon ; ) {
  316.         while ( ! (imes=(struct IntuiMessage *)GetMsg(wRq->UserPort)) ) {
  317.             if ( redisplay_flag ) {
  318.                 /* update in-gadget filenames */
  319.                 i = ((maxent-DENTS) * (ULONG)cc_prop.VertPot + MAXBODY/2)
  320.                         / MAXBODY;
  321.                 if ( i > maxent-DENTS ) {
  322.                     i = maxent-DENTS;
  323.                     if ( i < 0 )   i = 0;
  324.                 }
  325.                 curent = i;
  326.                 display_names();
  327.                 redisplay_flag = FALSE;
  328.             } /* End If redisplay_flag */
  329.             if ( more ) {
  330.                 if (pnam = dmore())   /* Continue to read the directory */
  331.                     notify(pnam);      /* Yucko error   */
  332.                 /* if ( maxent <= DENTS ) redisplay_flag = TRUE; */
  333.             } else /* not more */
  334.                 WaitPort(wRq->UserPort);
  335.         } /* End While There Is No Message */
  336.         igad = (struct Gadget *)imes->IAddress;
  337.         class = imes->Class;
  338.         ReplyMsg(imes);
  339.  
  340.         switch (class) {
  341.         case MOUSEMOVE:      
  342.             redisplay_flag = TRUE;   
  343.             break;
  344.  
  345.         case GADGETUP:
  346.         case GADGETDOWN:
  347.             switch ( i = igad->GadgetID) {
  348.             case FGAD+6:
  349.             case FGAD+7:
  350.             case FGAD+8:
  351.             case FGAD+9:
  352.             case FGAD+10:       /* Replace file or directory name   */
  353.                 pnam = rname[i - (FGAD+6)].IText;
  354.                 if ( rname[igad->GadgetID - (FGAD+6)].NextText == NL ) {
  355.                     RemoveGadget(wRq,&ogx);
  356.                     for (i=0; i<DSIZE; i++)      ddef[i] = *pnam++;
  357.                     AddGadget(wRq,&ogx,-1L);
  358.                     RefreshGadgets(&ogx,wRq,(long)NL);
  359.                     break;
  360.                 } else {
  361.                     RemoveGadget(wRq,&og5);
  362.                     rfnam(ddir,pnam);
  363.                     AddGadget(wRq,&og5,-1L);
  364.                     RefreshGadgets(&og5,wRq,(long)NL);
  365.                 }
  366.             case FGAD+5:
  367.                 if ( pnam = dinit(ddir) )
  368.                     notify(pnam);
  369.             case FGAD+3:
  370.                 redisplay_flag = TRUE;
  371.                 break;
  372.  
  373.             case FGAD+11:      /* Name gadget, OTAY gadget   */
  374.             case FGAD+1:
  375.                 retval = ddef;
  376.             case FGAD+2:      /* Cancel gadget   */
  377.                 keepon = FALSE;
  378.             }
  379.         }
  380.     }
  381.  
  382.     FreeMem(FirstEntry,(long)DBUFSIZ );
  383.     FreeMem(dir_info,(long)sizeof(struct FileInfoBlock));
  384.     free_pdir();
  385.  
  386.     CloseWindowSafely(wRq);
  387.     return retval;
  388. }
  389.  
  390. STATIC free_pdir()
  391. {
  392.     if ( pdir ) {
  393.         UnLock(pdir);
  394.         pdir = NL;
  395.     }
  396. }
  397.  
  398. /*****************************************************************
  399. * dinit()
  400. *   Initialize the fib for directory muck.  Null return
  401. * is good, else return is a pointer to an error string      */
  402.  
  403. STATIC TEXT *dinit(subdir)
  404. char *subdir;
  405. {
  406.     more = FALSE;
  407.     curent = maxent = 0;
  408.  
  409.     NextEntry = FirstEntry;      /* Allocate from here   */
  410.     ListHead.next = NL;          /* Clear the boogie     */
  411.  
  412.     free_pdir();   /* Unlock any old lock... */
  413.  
  414.     if (! (pdir=(struct FileLock *)Lock(subdir,(ULONG)ACCESS_READ)) )
  415.         return "Wrong Diskette?";
  416.     if ( ! Examine(pdir, dir_info) )   return "Wierd Disk Error";
  417.     if ( dir_info->fib_DirEntryType < 0L )   return "Bizzare Alert!!";
  418.  
  419.     more = TRUE;
  420.     return dmore();
  421. }
  422.  
  423.  
  424. STATIC TEXT *dmore()
  425. {
  426.     FAST struct dirent   *p_D = NextEntry;
  427.     FAST struct dirent   *ptr = (struct dirent *)&ListHead;
  428.     FAST struct dirent   *plink;
  429.  
  430.     FAST   TEXT   *p_mung;
  431.  
  432.     FAST long    i;
  433.  
  434.     FAST unsigned long VertBody;    /* KosmoSoft */
  435.  
  436.     if ( ! more )   return NL;
  437.  
  438.     if ( ExNext( pdir, dir_info ) ) {
  439.  
  440.  
  441.         if ( (ULONG)p_D >=
  442.             ((ULONG)FirstEntry + (ULONG)DBUFSIZ - (ULONG)sizeof(struct dirent)) ) {
  443.             more = FALSE;
  444.             return "Directory Truncated!";
  445.         }
  446.  
  447.  
  448. /* Here you can add a file/directory filter   */
  449. /* filename text string is at &p_D->dE[0]     */
  450.         p_D->isfile = ( dir_info->fib_DirEntryType < 0L );
  451.  
  452.         p_mung = &p_D->dE[0];
  453.         for ( i=0; i<FCHARS; i++)
  454.             if ( ! (*p_mung++ = dir_info->fib_FileName[i]) )   break;
  455.  
  456.         i = (long)p_mung;
  457.         NextEntry = (struct dirent *)( (i+5L) & ~3L );
  458.  
  459.         for ( i=maxent++; i>=0; i--) {
  460.             /* Start at the top and walk down until the new name */
  461.             /* is 'smaller' than the next one (???) */
  462.             if ( ! (plink = ptr->next)  )   break;
  463.             if ( alpha_lower(p_D,plink) )   break;
  464.             ptr = plink;
  465.         }
  466.         /* Insert the new name in front of the next one */
  467.         p_D->next = plink;
  468.         ptr->next = p_D;
  469.         redisplay_flag = maxent - i <= curent + DENTS;
  470.  
  471.         /* Adjust the scroll bar */
  472.         if (maxent <= DENTS)
  473.             VertBody = MAXBODY;
  474.         else
  475.             VertBody = (ULONG) MAXBODY * DENTS / maxent;
  476.  
  477.         ModifyProp(&og3, wRq, NULL, (ULONG) cc_prop.Flags,
  478.             0L, (ULONG) cc_prop.VertPot, 0L, VertBody);
  479.  
  480.         return NL;
  481.     }
  482.     else return ( IoErr() == ERROR_NO_MORE_ENTRIES) ?
  483.     (char *)(more = (long)NL) : "Error Reading Directory!!!";
  484. }
  485.  
  486.  
  487. /* dedicated alphabetizing function for dmore()   */
  488.  
  489. STATIC alpha_lower(snew,sold)
  490. struct dirent *snew,*sold;
  491. {
  492.     FAST struct dirent *pnew = snew;
  493.     FAST TEXT *ps1,*ps2, c,d;
  494.  
  495.     if ( pnew->isfile == sold->isfile) {
  496.         ps1 = &pnew->dE[0];
  497.         ps2 = &sold->dE[0];
  498.         while ( (c=*ps1++) ) {
  499.             if ( c > (d=*ps2++) )   return FALSE;
  500.             else if ( c < d )      break;
  501.         }
  502.         return TRUE;
  503.     }
  504.     return !pnew->isfile; /* Directories first */
  505. }   
  506.  
  507.  
  508.  
  509. /* Display directory stuff   */
  510.  
  511. STATIC display_names()
  512. {
  513.     FAST long   i,new;
  514.     FAST long   x,y;
  515.     FAST struct dirent *ohboy = (struct dirent *)&ListHead;
  516.  
  517.     new = curent;
  518.     for ( i=0; i<new; i++)   ohboy = ohboy->next;
  519.  
  520.     y = 20L;
  521.     for (i=0; i<DENTS; i++) {
  522.         y += (x=10);
  523.         rname[i].NextText = NL;
  524.         rname[i].IText = "";
  525.         rname[i].LeftEdge = 0;
  526.         if ( (new+i) < maxent ) {
  527.             ohboy = ohboy->next;
  528.             rname[i].IText = &ohboy->dE[0];
  529.             if ( ohboy->isfile )   PrintIText(wRp,&rname[i],10L,y);
  530.             else {
  531.                 rname[i].LeftEdge = 48;
  532.                 PrintIText(wRp,&saydir,10L,y);
  533.                 PrintIText(wRp,&rname[i],10L,y);
  534.                 rname[i].NextText = &saydir;
  535.             }
  536.             x = wRp->cp_x;
  537.         }
  538.         if ( x < ZWDTH+10 )   RectFill(wRp,x,y,(long)(ZWDTH+10),(long)(y+8L));
  539.     }
  540. }
  541.  
  542.  
  543. /**************************************************
  544. * rfnam()
  545. *   Combines dir, plus name into dir   */
  546.  
  547. STATIC rfnam(dir,fil_nam)
  548. char *dir,*fil_nam;
  549. {
  550.     FAST char   *pdst = dir;
  551.     FAST char   *psrc = fil_nam;
  552.     FAST char   c = ':';
  553.  
  554.     while ( *pdst )
  555.         c = *pdst++;
  556.     if ( c != ':')   *pdst++ = '/';
  557.  
  558.     while ( *pdst++ = *psrc++ )
  559.         ;
  560. }
  561.  
  562. STATIC struct IntuiText b_txt = {
  563.     0,1,JAM2, 5,20,NL,NL,    NL};
  564. STATIC struct IntuiText p_txt = {
  565.     0,1,JAM2, 5,3,NL,"OK", NL};
  566.  
  567. /****************************************************************/
  568. /* notify(txt)                                                  */
  569. /*   Prompts for Yes/No response                                */
  570.  
  571. STATIC notify(txt)
  572. TEXT *txt;
  573. {
  574.     b_txt.IText = txt;
  575.     AutoRequest(wRq,&b_txt,0L,&p_txt,0L,0L,
  576.     (long)(IntuiTextLength(&b_txt)+50L),70L);
  577. }
  578.  
  579. /* CloseWindowSafely()
  580. *       This module should be used whenever you are sharing an IDCMP
  581. * message port with more than one window.  Rather than calling CloseWindow(),
  582. * you should use CloseWindowSafely().  This will keep Intuition from
  583. * Guru Meditation, and thus is considered a good thing.  You should still
  584. * use CloseWindow for the very last window you close.
  585. *       The reason this is needed, is because Intuition will re-claim
  586. * any outstanding messages for a window when the window is closed. But...
  587. * it can't take them out of your message port. Thus, you will receive
  588. * invalid messages and bad things will happen.  Very bad things.
  589. *       This code is a slightly condensed version of the same routine
  590. * written by Neil Katin of Amiga for the April '86 Commodore Developers
  591. * Newsletter, Amiga Mail (tm).
  592. */
  593.  
  594. /*
  595. #include <exec/types.h>
  596. #include <exec/nodes.h>
  597. #include <exec/lists.h>
  598. #include <exec/ports.h>
  599. #include <intuition/intuition.h>
  600. #include <functions.h>
  601. */
  602.  
  603. void CloseWindowSafely( p_wind )
  604. struct Window   *p_wind;
  605. {
  606.     register struct IntuiMessage    *msg;
  607.     register struct IntuiMessage    *succ;
  608.     register struct Window          *win = p_wind;
  609.     register struct MsgPort         *mp = (struct MsgPort *)win->UserPort;
  610.  
  611.     Forbid();
  612.  
  613.     msg = (struct IntuiMessage *)mp->mp_MsgList.lh_Head;
  614.  
  615.     while ( succ=(struct IntuiMessage *)msg->ExecMessage.mn_Node.ln_Succ ) {
  616.         if ( msg->IDCMPWindow == win ) {
  617.             Remove ( msg );
  618.             ReplyMsg( msg );
  619.         }
  620.         msg = succ;
  621.     }
  622.     win->UserPort = NULL;
  623.     ModifyIDCMP( win, 0L );
  624.     Permit();
  625.     CloseWindow( win );
  626. }
  627.  
  628.  
  629.